<?php
namespace App\Services\Api;


use App\Events\OrderSubmitEvent;
use App\Models\Order;
use App\Models\PartnerOrder;
use App\Models\User;
use EasyWeChat\Factory;
use App\Services\BaseServices as Base;

class PaymentService extends Base
{


    /**
     * @var User $user
     */
    public $user;

    /**
     * @var Order $order
     */
    public $order;

    /**
     * @var PartnerOrder $p_order
     */
    public $p_order;

    /**
     * @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function orderPayment()
    {
        $param = [
            'trade_type'   => 'JSAPI',
            'body'         => '购买商品',
            'out_trade_no' => $this->order->order_sn,
            'total_fee'    => bcmul($this->order->pay_amount, 100),
            'notify_url'   => url('api/order/notify')
        ];

        return $this->pay($param);
    }


    /**
     * @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function partnerPayment()
    {
        $param = [
            'trade_type'   => 'JSAPI',
            'body'         => $this->p_order->product_name,
            'out_trade_no' => $this->p_order->order_sn,
            'total_fee'    => $this->p_order->amount * 100,
            'notify_url'   => url('api/partner/order-notify')
        ];

        return $this->pay($param);
    }

    /**
     * 统一支付下单接口
     * @param $param
     * @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function pay($param)
    {
        $app = Factory::payment(config("wechat.mini_program.default"));

        $result = $app->order->unify(array_merge($param,['openid' => $this->user->openid]));

        if ($result['return_code'] == 'SUCCESS') {
            $prepayId = $result['prepay_id'];
            $config = $app->jssdk->sdkConfig($prepayId);
            return $config;
        } else {
            return $result;
        }
    }


    /**
     * 微信支付异步通知
     * @param $object
     * @throws \EasyWeChat\Kernel\Exceptions\Exception
     */
    public function notify($object)
    {
        $app = Factory::payment(config("wechat.payment.default"));

        $app->handlePaidNotify(function ($message, $fail) use ($object){

            if ($message['return_code'] === 'SUCCESS' && $message['result_code'] === 'SUCCESS') {

                \Log::channel('wechat')->info('微信支付回调', $message);

                 //处理商品订单
                 if($object instanceof Order){

                     $order = $object::where('order_sn', $message['out_trade_no'])->where('status', Order::UN_PAY)->first();

                     if($order){
                         event((new OrderSubmitEvent($order)));
                     }

                 }elseif ($object instanceof PartnerOrder){
                     $order = $object::where('order_sn', $message['out_trade_no'])->where('status', PartnerOrder::UN_PAY)->first();
                     if($order){
                         PartnerServices::successPay($order);
                     }
                 }


                 //TODO 其他


                //处理异步回调成功信息
                $return = ['return_code'=>'SUCCESS','return_msg'=>'OK'];
                $xml = '<xml>';
                foreach($return as $k=>$v){
                    $xml.='<'.$k.'><![CDATA['.$v.']]></'.$k.'>';
                }
                $xml.='</xml>';

                echo $xml;

            } else {
                \Log::channel('wechat')->info('微信支付失败回调');
                return $fail('失败');
            }
        });
    }


}